<template>
  <div>
    <!-- 轮播图和下载客服端 -->
    <!-- top banner大盒子 -->
    <div
      class="top-banner"
      :style="{
        backgroundImage: 'url(' + backgroundImageUrl + ')',
        backgroundSize: '6000px',
        backgroundPosition: 'center center'
      }"
      @mouseover="enterHandle"
      @mouseout="leaveHandle"
    >
      <div class="wrap">
        <template v-if="backgroundImageUrlList.length !== 0">
          <!-- 轮播图 -->
          <div class="banner" ref="linkRef">
            <a :href="linkUrl" target="_blank" v-if="linkUrl.includes('http')"
              ><img :src="imageUrl" alt="" ref="imgRef"
            /></a>
            <router-link :to="linkUrl" v-else
              ><img :src="imageUrl" alt="" ref="imgRef"
            /></router-link>
          </div>
          <!-- 轮播图控制点 -->
          <div class="dots" ref="dotsRef">
            <a
              href="javascript:;"
              class="dot"
              :class="index === 0 ? 'current' : ''"
              v-for="(val, index) in imageUrlList"
              :key="index"
              @click="dotsClickHandle(index, $event)"
            ></a>
          </div>
          <!-- 轮播图向后按钮 -->
          <a href="javascript:;" class="banner-btn back" ref="BackRef" @click="clickHandle(-1)"></a>
          <!-- 轮播图向前按钮 -->
          <a
            href="javascript:;"
            class="banner-btn forward"
            ref="ForwardRef"
            @click="clickHandle(1)"
          ></a>
          <!-- 下载客户端 -->
          <div class="download">
            <router-link to="/download"></router-link>
            <p>PC 安卓 iPhone WP iPad Mac 六大客户端</p>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<script>
import { Banners } from '@/api/home.js'
import { reject } from 'q'
export default {
  data() {
    return {
      // 轮播图数据
      banners: null,
      // 所有轮播图链接
      links: [],
      // 轮播图url列表
      imageUrlList: [],
      // 轮播背景图url列表
      backgroundImageUrlList: [],
      // 轮播图url
      imageUrl: '',
      // 轮播背景图url
      backgroundImageUrl: '',
      // 轮播图链接
      linkUrl: '',
      // 当前轮播图的index
      currentId: 0,
      // 轮播图定时器标志
      timer: null,
      // 淡出定时器
      timeoutTimer: null
    }
  },
  methods: {
    // 获取banners数据
    async getBanners() {
      // 发起请求
      const { data: res } = await Banners()
      this.banners = res.banners
      // 对请求数据进行处理，提取imageUrl和a标签的href
      this.banners.forEach(item => {
        if (item.url) {
          this.links.push(item.url)
        } else {
          const temp =
            item.targetType === 1 ? `/song?id=${item.targetId}` : `/mv?id=${item.targetId}`
          this.links.push(item.targetType === 10 ? `/album?id=${item.targetId}` : temp)
        }
        // 对imageURL进行处理
        this.imageUrlList.push(item.imageUrl + '?imageView&quality=89')
        this.backgroundImageUrlList.push(item.imageUrl + '?imageView&blur=40x20')
      })
      // 初始化赋值
      this.linkUrl = this.links[0]
      this.imageUrl = this.imageUrlList[0]
      this.backgroundImageUrl = this.backgroundImageUrlList[0]
      // 提前加载图片
      let urls = this.imageUrlList.concat(this.backgroundImageUrlList)
      this.limitLoad(urls, this.loadImage, 5)
    },
    // 异步加载图片
    loadImage(url) {
      return new Promise((resolve, reject) => {
        let img = new Image()
        img.onload = () => {
          resolve(img)
        }
        img.onerror = () => {
          reject(new Error('request image failed')) 
        }
        img.src = url
      })
    },
    // promise限制并发数
    limitLoad(urls, handler, limit) {
      let sequence = [...urls]
      let promises = sequence.splice(0, limit).map((url, index) => {
        return handler(url).then(() => index)
      })
      return sequence
        .reduce((pCollect, url) => {
          return pCollect
            .then(() => {
              return Promise.race(promises)
            })
            .then(fastestIndex => {
              promises[fastestIndex] = handler(url).then(() => fastestIndex)
            })
            .catch(err => console.log(err))
        }, Promise.resolve())
        .then(() => {
          return Promise.all(promises)
        })
    },
    // 轮播图功能
    slideShow() {
      if (this.timer) {
        clearInterval(this.timer)
      }
      // 开启迭代器
      this.timer = window.setInterval(() => {
        // 设置图片出现时opacity为1，没有transition效果
        this.$refs.linkRef.style.transition = 'none 0s ease-in'
        this.$refs.linkRef.style.opacity = '1'
        // 改变currentId
        this.currentId += 1
        // 判断currentID是否超过长度
        if (this.currentId > this.banners.length - 1) this.currentId = 0
        // 图片淡出效果。在切换图片前，设置图片opacity为0，并设置transition效果
        this.timeoutTimer = window.setTimeout(() => {
          this.$refs.linkRef.style.opacity = '0'
          this.$refs.linkRef.style.transition = 'opacity 0.4s ease-out'
        }, 4650)
      }, 5000)
    },
    // 点击按钮切换图片
    clickHandle(step) {
      // 判断currentid变化后是否在范围内，如果不是进行自定义赋值
      if (this.currentId + step < 0) {
        this.currentId = this.banners.length - 1
      } else if (this.currentId + step > this.banners.length - 1) {
        this.currentId = 0
      } else {
        this.currentId += step
      }
    },
    // 鼠标进入，暂停自动轮播
    enterHandle() {
      if (this.timer) {
        clearInterval(this.timer)
        clearTimeout(this.timeoutTimer)
        this.timer = null
        this.timeoutTimer = null
      }
      this.$refs.linkRef.style.opacity = '1'
    },
    // 鼠标离开，开启自动轮播
    leaveHandle() {
      this.slideShow()
    },
    // 轮播图控制点点击事件
    dotsClickHandle(index) {
      this.currentId = index
    }
  },
  watch: {
    // 监听currentID变化，对图片和点样式进行切换
    currentId(val) {
      // 点样式变化
      const dotList = this.$refs.dotsRef.childNodes
      dotList.forEach(item => {
        item.classList.remove('current')
      })
      dotList[val].classList.toggle('current')
      // 图片链接切换
      this.linkUrl = this.links[val]
      this.imageUrl = this.imageUrlList[val]
      this.backgroundImageUrl = this.backgroundImageUrlList[val]
    }
  },
  created() {
    // 获取banners数据
    this.getBanners()
    if (this.timer) {
      clearInterval(this.timer)
    }
    this.slideShow()
  },
  beforeDestroy() {
    // 结束时销毁定时器
    clearInterval(this.timer)
    clearInterval(this.timeoutTimer)
  }
}
</script>

<style lang="less">
@import './banner.less';
</style>
